package linker.chat;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

import linker.account.Account;
import linker.account.ManageAccount;
import linker.buddy.BuddyInfo;
import linker.file.FileFunction;
import linker.list.CellRender;
import linker.list.DefaultListItem;
import linker.list.Model;
import linker.plugin.PluginManager;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;

/**
 * 
 * @version linker 0.93
 * @author Jianfeng coxzjkwl@gmail.com
 * 
 */
public class ChatCell extends DefaultListItem {

	static final long serialVersionUID = 1L;

	private Presence.Type type = null;

	private Presence.Mode mode = null;

	private String status = null;

	private String user = null;

	private String name = null;

	private StringBuffer chatLog;

	private RosterEntry entry;

	private Chat chat;

	private String fullJID = null;

	private ChatWindow chatWindow = null;

	private JPopupMenu lastMenu = null;

	private boolean hasMessage = false;

	public static String imagePath = ManageAccount.getImagePath();

	public static ImageIcon freeIcon = new ImageIcon(imagePath + "free.png");

	public static ImageIcon offIcon = new ImageIcon(imagePath + "off.png");

	public static ImageIcon messageIcon = new ImageIcon(imagePath
			+ "message.png");

	public static ImageIcon awayIcon = new ImageIcon(imagePath + "away.png");

	public static ImageIcon busyIcon = new ImageIcon(imagePath + "busy.png");

	public ImageIcon statusIcon = freeIcon;

	public ChatCell(final RosterEntry entry) {
		this.entry = entry;

		user = entry.getUser();
		name = entry.getName();
		chatLog = new StringBuffer("");
	}

	public void setMessage(Message message) {
		if (message.getBody() == null)
			return;

		if (name == null)
			display(user + ":" + message.getBody());
		else
			display(name + ":" + message.getBody());
	}

	protected void display(String body) {
		if (chatWindow != null)
			chatWindow.display(body);
		else {
			if (!hasMessage)
				addMessageNotifier();

			chatLog.append(body);
			chatLog.append("\n");
		}
	}

	public void send(String message) {
		try {
			chat.sendMessage(message);
			display(Account.getName() + ":" + message);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public RosterEntry getEntry() {
		return entry;
	}

	public String toString() {

		if (name == null)
			return user + getStatus();

		return name + getStatus();
	}

	public String getStatus() {
		if (status != null && status.trim().length() > 0)
			return "(" + status + ")";
		else
			return "";
	}

	public void addMessageNotifier() {
		hasMessage = true;
		Account.addMessage(this);
	}

	public void removeMessageNotify() {
		hasMessage = false;
		Account.removeMessage(this);
	}

	public Presence.Type getType() {
		return type;
	}

	public Presence.Mode getMode() {
		return mode;
	}

	public void setPresence(Presence presence) {
		status = presence.getStatus();
		type = presence.getType();
		mode = presence.getMode();
		fullJID = presence.getFrom();
	}

	public String getFullJID() {
		return fullJID;
	}

	public void setChatWindow(ChatWindow chatWindow) {
		this.chatWindow = chatWindow;

		if (chatWindow == null)
			chat = null;
	}

	public String getChatLog() {
		String temp = new String(chatLog);
		chatLog = new StringBuffer();

		return temp;
	}

	public void doubleClick() {
		if (chatWindow == null) {
			chatWindow = new ChatWindow(this);
			chat = Account.getConnection().getChatManager().createChat(user,
					new MessageListener() {
						public void processMessage(Chat arg0, Message arg1) {
						}
					});

			removeMessageNotify();
			Account.getMessageList().removeElement(this);
		}
	}

	public void rightClick() {
	}

	public ActionListener getActionListener() {
		ActionListener listener = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (e.getActionCommand() == "Chat") {
					lastMenu.setVisible(false);
					lastMenu = null;
					doubleClick();
				} else if (e.getActionCommand() == "SendFile") {
					lastMenu.setVisible(false);
					lastMenu = null;
					FileFunction.sendFile(getFullJID(), null);
				} else if (e.getActionCommand() == "Info") {
					lastMenu.setVisible(false);
					lastMenu = null;
					new BuddyInfo(entry);
				} else if (e.getActionCommand() == "SendPlugin") {
					lastMenu.setVisible(false);
					lastMenu = null;
					PluginManager.setJID(getFullJID());
					PluginManager.getPluginManager().setVisible(true);
				}
			}
		};
		return listener;
	}

	public JPopupMenu getPopupMenu() {

		JPopupMenu menu = new JPopupMenu();
		JMenuItem item = new JMenuItem("Chat");
		item.addActionListener(getActionListener());
		menu.add(item);
		item = new JMenuItem("SendFile");
		item.addActionListener(getActionListener());
		menu.add(item);
		item = new JMenuItem("SendPlugin");
		item.addActionListener(getActionListener());
		menu.add(item);
		item = new JMenuItem("Info");
		item.addActionListener(getActionListener());
		menu.add(item);

		lastMenu = menu;
		return menu;
	}

	public String getUser() {
		return user;
	}

	public boolean hasMessage() {
		return hasMessage;
	}

	public void setRender(CellRender render) {

		if (getType() == null || getType() != Presence.Type.available)
			statusIcon = offIcon;
		else if (hasMessage())
			statusIcon = messageIcon;
		else if (getMode() == Presence.Mode.away)
			statusIcon = awayIcon;
		else if (getMode() == Presence.Mode.dnd)
			statusIcon = busyIcon;
		else
			statusIcon = freeIcon;

		render.setIcon(statusIcon);
		render.setToolTipText(getEntry().getUser() + getStatus());
	}

	public void leftClick() {
	}

	public Model getModelList() {
		return null;
	}

}
